package org.finesys.common.core.support.serializer;

import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.finesys.common.core.annotation.ImgUrl;
import org.finesys.common.core.constants.RegexpConstants;
import org.finesys.common.core.util.SpringUtil;
import org.finesys.common.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;

public class ImgUrlSerialize extends JsonSerializer<Object> implements ContextualSerializer {
    @Value("${fine.oss.resources-url}")
    private String imgDomain;

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (Objects.isNull(value)) {
            gen.writeString(StrUtil.EMPTY);
        } else if (value instanceof List) {
            writeList((List<?>) value, gen);
        } else {
            writeString(value, gen);
        }
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        if (Objects.isNull(beanProperty)) {
            return serializerProvider.findNullValueSerializer(null);
        }

        if (Objects.equals(beanProperty.getType().getRawClass(), String.class)
                || Objects.equals(beanProperty.getType().getRawClass(), List.class)) {
            ImgUrl imgUrl = beanProperty.getAnnotation(ImgUrl.class);
            imgUrl = Objects.isNull(imgUrl) ? beanProperty.getContextAnnotation(ImgUrl.class) : imgUrl;

            if (Objects.nonNull(imgUrl)) {
                return SpringUtil.getBean(ImgUrlSerialize.class);
            }
        }

        return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
    }

    private void writeList(List<?> value, JsonGenerator gen) throws IOException {
        if (CollectionUtils.isEmpty(value)) {
            gen.writeArray(new java.lang.String[]{}, 0, 0);
        }

        List<String> collect = (List<String>) value.stream().map(this::buildString).collect(Collectors.toList());
        gen.writeArray(collect.toArray(new String[0]), 0, collect.size());
    }

    private void writeString(Object value, JsonGenerator gen) throws IOException {
        gen.writeString(buildString(value));
    }

    public String buildString(Object value) {
        if (!(value instanceof String)) {
            return StrUtil.EMPTY;
        }

        String str = (String) value;
        if (StrUtil.isBlank(str)) {
            return StrUtil.EMPTY;
        }

        StringBuilder sb = new StringBuilder();

        Pattern pattern = Pattern.compile(RegexpConstants.HTTP_PROTOCOL_REGEXP);
        boolean res = pattern.matcher(str).find();

        // 图片为http协议开头，直接返回
        if (res) {
            sb.append(str);
        } else {
            sb.append(imgDomain).append(str);
        }

        return sb.toString();
    }
}